package com.uniflow.controller;

import com.uniflow.common.PageResult;
import com.uniflow.common.Result;
import com.uniflow.entity.Form;
import com.uniflow.service.UniflowFormService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 表单管理控制器
 */
@Api(tags = "表单管理")
@RestController
@RequestMapping("/api/v1/forms")
public class FormController {
    
    @Autowired
    private UniflowFormService formService;
    
    /**
     * 分页查询表单列表
     */
    @ApiOperation("分页查询表单列表")
    @GetMapping
    public Result<PageResult<Form>> getFormList(
            @ApiParam("页码") @RequestParam(defaultValue = "1") int pageNum,
            @ApiParam("页大小") @RequestParam(defaultValue = "10") int pageSize,
            @ApiParam("表单名称") @RequestParam(required = false) String name,
            @ApiParam("表单分类") @RequestParam(required = false) String category,
            @ApiParam("发布状态") @RequestParam(required = false) Boolean published,
            @ApiParam("启用状态") @RequestParam(required = false) Boolean enabled,
            @ApiParam("创建人") @RequestParam(required = false) String createdBy,
            @ApiParam("包含使用统计") @RequestParam(defaultValue = "false") boolean includeUsage) {
        
        PageResult<Form> result = formService.getFormList(pageNum, pageSize, name, category, 
                published, enabled, createdBy, includeUsage);
        return Result.success(result);
    }
    
    /**
     * 根据ID查询表单详情
     */
    @ApiOperation("根据ID查询表单详情")
    @GetMapping("/{id}")
    public Result<Form> getFormById(@ApiParam("表单ID") @PathVariable String id) {
        Form form = formService.getFormById(id);
        if (form == null) {
            return Result.error("表单不存在");
        }
        return Result.success(form);
    }
    
    /**
     * 根据名称查询表单
     */
    @ApiOperation("根据名称查询表单")
    @GetMapping("/name/{name}")
    public Result<Form> getFormByName(@ApiParam("表单名称") @PathVariable String name) {
        Form form = formService.getFormByName(name);
        if (form == null) {
            return Result.error("表单不存在");
        }
        return Result.success(form);
    }
    
    /**
     * 根据外部ID查询表单
     */
    @ApiOperation("根据外部ID查询表单")
    @GetMapping("/external/{externalId}")
    public Result<Form> getFormByExternalId(@ApiParam("外部ID") @PathVariable String externalId) {
        Form form = formService.getFormByExternalId(externalId);
        if (form == null) {
            return Result.error("表单不存在");
        }
        return Result.success(form);
    }
    
    /**
     * 创建表单
     */
    @ApiOperation("创建表单")
    @PostMapping
    public Result<Form> createForm(@Valid @RequestBody CreateFormRequest request) {
        Form form = new Form();
        form.setName(request.getName());
        form.setTitle(request.getTitle());
        form.setDescription(request.getDescription());
        form.setCategory(request.getCategory());
        form.setConfig(request.getConfig());
        form.setFields(request.getFields());
        form.setStyle(request.getStyle());
        form.setExternalId(request.getExternalId());
        form.setCreatedBy(request.getCreatedBy());
        form.setCreatedByName(request.getCreatedByName());
        
        Form createdForm = formService.createForm(form);
        return Result.success(createdForm);
    }
    
    /**
     * 更新表单
     */
    @ApiOperation("更新表单")
    @PutMapping("/{id}")
    public Result<Form> updateForm(@ApiParam("表单ID") @PathVariable String id, 
                                  @Valid @RequestBody UpdateFormRequest request) {
        Form form = formService.getFormById(id);
        if (form == null) {
            return Result.error("表单不存在");
        }
        
        form.setName(request.getName());
        form.setTitle(request.getTitle());
        form.setDescription(request.getDescription());
        form.setCategory(request.getCategory());
        form.setConfig(request.getConfig());
        form.setFields(request.getFields());
        form.setStyle(request.getStyle());
        form.setUpdatedBy(request.getUpdatedBy());
        form.setUpdatedByName(request.getUpdatedByName());
        
        Form updatedForm = formService.updateForm(form);
        return Result.success(updatedForm);
    }
    
    /**
     * 删除表单
     */
    @ApiOperation("删除表单")
    @DeleteMapping("/{id}")
    public Result<Void> deleteForm(@ApiParam("表单ID") @PathVariable String id) {
        formService.deleteForm(id);
        return Result.success();
    }
    
    /**
     * 批量删除表单
     */
    @ApiOperation("批量删除表单")
    @DeleteMapping("/batch")
    public Result<Void> batchDeleteForms(@RequestBody BatchDeleteRequest request) {
        formService.batchDeleteForms(request.getIds());
        return Result.success();
    }
    
    /**
     * 发布表单
     */
    @ApiOperation("发布表单")
    @PostMapping("/{id}/publish")
    public Result<Void> publishForm(@ApiParam("表单ID") @PathVariable String id) {
        formService.publishForm(id);
        return Result.success();
    }
    
    /**
     * 取消发布表单
     */
    @ApiOperation("取消发布表单")
    @PostMapping("/{id}/unpublish")
    public Result<Void> unpublishForm(@ApiParam("表单ID") @PathVariable String id) {
        formService.unpublishForm(id);
        return Result.success();
    }
    
    /**
     * 启用表单
     */
    @ApiOperation("启用表单")
    @PostMapping("/{id}/enable")
    public Result<Void> enableForm(@ApiParam("表单ID") @PathVariable String id) {
        formService.enableForm(id);
        return Result.success();
    }
    
    /**
     * 禁用表单
     */
    @ApiOperation("禁用表单")
    @PostMapping("/{id}/disable")
    public Result<Void> disableForm(@ApiParam("表单ID") @PathVariable String id) {
        formService.disableForm(id);
        return Result.success();
    }
    
    /**
     * 复制表单
     */
    @ApiOperation("复制表单")
    @PostMapping("/{id}/copy")
    public Result<Form> copyForm(@ApiParam("表单ID") @PathVariable String id, 
                                @RequestBody CopyFormRequest request) {
        Form copiedForm = formService.copyForm(id, request.getName(), request.getTitle(), 
                request.getCopiedBy(), request.getCopiedByName());
        return Result.success(copiedForm);
    }
    
    /**
     * 批量更新表单排序
     */
    @ApiOperation("批量更新表单排序")
    @PostMapping("/batch-sort")
    public Result<Void> batchUpdateSort(@RequestBody BatchUpdateSortRequest request) {
        // 转换类型
        List<UniflowFormService.FormSort> formSorts = new ArrayList<>();
        for (BatchUpdateSortRequest.FormSort requestSort : request.getFormSorts()) {
            UniflowFormService.FormSort serviceSort = new UniflowFormService.FormSort();
            serviceSort.setId(requestSort.getId());
            serviceSort.setSortOrder(requestSort.getSortOrder());
            formSorts.add(serviceSort);
        }
        formService.batchUpdateSort(formSorts);
        return Result.success();
    }
    
    /**
     * 根据分类查询表单列表
     */
    @ApiOperation("根据分类查询表单列表")
    @GetMapping("/category/{category}")
    public Result<List<Form>> getFormsByCategory(@ApiParam("分类") @PathVariable String category) {
        List<Form> forms = formService.getFormsByCategory(category);
        return Result.success(forms);
    }
    
    /**
     * 查询已发布的表单列表
     */
    @ApiOperation("查询已发布的表单列表")
    @GetMapping("/published")
    public Result<List<Form>> getPublishedForms() {
        List<Form> forms = formService.getPublishedForms();
        return Result.success(forms);
    }
    
    /**
     * 查询表单分类列表
     */
    @ApiOperation("查询表单分类列表")
    @GetMapping("/categories")
    public Result<List<String>> getFormCategories() {
        List<String> categories = formService.getFormCategories();
        return Result.success(categories);
    }
    
    /**
     * 检查表单名称是否可用
     */
    @ApiOperation("检查表单名称是否可用")
    @GetMapping("/check-name")
    public Result<Boolean> checkFormNameAvailable(
            @ApiParam("表单名称") @RequestParam String name,
            @ApiParam("排除的表单ID") @RequestParam(required = false) String excludeId) {
        boolean available = formService.isFormNameAvailable(name, excludeId);
        return Result.success(available);
    }
    
    /**
     * 获取表单统计信息
     */
    @ApiOperation("获取表单统计信息")
    @GetMapping("/statistics")
    public Result<Map<String, Object>> getFormStatistics() {
        Map<String, Object> statistics = formService.getFormStatistics();
        return Result.success(statistics);
    }
    
    /**
     * 获取表单使用统计
     */
    @ApiOperation("获取表单使用统计")
    @GetMapping("/usage-statistics")
    public Result<List<Map<String, Object>>> getFormUsageStatistics(
            @ApiParam("限制数量") @RequestParam(defaultValue = "10") Integer limit) {
        List<Map<String, Object>> statistics = formService.getFormUsageStatistics(limit);
        return Result.success(statistics);
    }
    
    /**
     * 根据创建人统计表单数量
     */
    @ApiOperation("根据创建人统计表单数量")
    @GetMapping("/count-by-creator")
    public Result<List<Map<String, Object>>> getFormCountByCreator() {
        List<Map<String, Object>> statistics = formService.getFormCountByCreator();
        return Result.success(statistics);
    }
    
    /**
     * 根据分类统计表单数量
     */
    @ApiOperation("根据分类统计表单数量")
    @GetMapping("/count-by-category")
    public Result<List<Map<String, Object>>> getFormCountByCategory() {
        List<Map<String, Object>> statistics = formService.getFormCountByCategory();
        return Result.success(statistics);
    }
    
    /**
     * 增加表单版本
     */
    @ApiOperation("增加表单版本")
    @PostMapping("/{id}/increment-version")
    public Result<Void> incrementFormVersion(@ApiParam("表单ID") @PathVariable String id,
                                           @RequestParam String updatedBy,
                                           @RequestParam String updatedByName) {
        formService.incrementFormVersion(id, updatedBy, updatedByName);
        return Result.success();
    }
    
    /**
     * 验证表单字段
     */
    @ApiOperation("验证表单字段")
    @PostMapping("/validate-fields")
    public Result<Map<String, Object>> validateFormFields(@RequestBody ValidateFieldsRequest request) {
        Map<String, Object> result = formService.validateFormFields(request.getFields());
        return Result.success(result);
    }
    
    /**
     * 生成表单预览HTML
     */
    @ApiOperation("生成表单预览HTML")
    @PostMapping("/{id}/preview")
    public Result<String> generateFormPreview(@ApiParam("表单ID") @PathVariable String id) {
        String html = formService.generateFormPreviewHtml(id);
        return Result.success(html);
    }
    
    /**
     * 导入表单
     */
    @ApiOperation("导入表单")
    @PostMapping("/import")
    public Result<Form> importForm(@RequestParam("file") MultipartFile file,
                                  @RequestParam String importedBy,
                                  @RequestParam String importedByName) {
        // 这里可以实现表单导入逻辑
        return Result.error("功能暂未实现");
    }
    
    /**
     * 导出表单
     */
    @ApiOperation("导出表单")
    @GetMapping("/{id}/export")
    public Result<String> exportForm(@ApiParam("表单ID") @PathVariable String id) {
        // 这里可以实现表单导出逻辑
        return Result.error("功能暂未实现");
    }
    
    // 请求数据结构
    
    public static class CreateFormRequest {
        private String name;
        private String title;
        private String description;
        private String category;
        private Form.FormConfig config;
        private List<Form.FormField> fields;
        private Form.FormStyle style;
        private String externalId;
        private String createdBy;
        private String createdByName;
        
        // getters and setters
        public String getName() { return name; }
        public void setName(String name) { this.name = name; }
        public String getTitle() { return title; }
        public void setTitle(String title) { this.title = title; }
        public String getDescription() { return description; }
        public void setDescription(String description) { this.description = description; }
        public String getCategory() { return category; }
        public void setCategory(String category) { this.category = category; }
        public Form.FormConfig getConfig() { return config; }
        public void setConfig(Form.FormConfig config) { this.config = config; }
        public List<Form.FormField> getFields() { return fields; }
        public void setFields(List<Form.FormField> fields) { this.fields = fields; }
        public Form.FormStyle getStyle() { return style; }
        public void setStyle(Form.FormStyle style) { this.style = style; }
        public String getExternalId() { return externalId; }
        public void setExternalId(String externalId) { this.externalId = externalId; }
        public String getCreatedBy() { return createdBy; }
        public void setCreatedBy(String createdBy) { this.createdBy = createdBy; }
        public String getCreatedByName() { return createdByName; }
        public void setCreatedByName(String createdByName) { this.createdByName = createdByName; }
    }
    
    public static class UpdateFormRequest {
        private String name;
        private String title;
        private String description;
        private String category;
        private Form.FormConfig config;
        private List<Form.FormField> fields;
        private Form.FormStyle style;
        private String updatedBy;
        private String updatedByName;
        
        // getters and setters
        public String getName() { return name; }
        public void setName(String name) { this.name = name; }
        public String getTitle() { return title; }
        public void setTitle(String title) { this.title = title; }
        public String getDescription() { return description; }
        public void setDescription(String description) { this.description = description; }
        public String getCategory() { return category; }
        public void setCategory(String category) { this.category = category; }
        public Form.FormConfig getConfig() { return config; }
        public void setConfig(Form.FormConfig config) { this.config = config; }
        public List<Form.FormField> getFields() { return fields; }
        public void setFields(List<Form.FormField> fields) { this.fields = fields; }
        public Form.FormStyle getStyle() { return style; }
        public void setStyle(Form.FormStyle style) { this.style = style; }
        public String getUpdatedBy() { return updatedBy; }
        public void setUpdatedBy(String updatedBy) { this.updatedBy = updatedBy; }
        public String getUpdatedByName() { return updatedByName; }
        public void setUpdatedByName(String updatedByName) { this.updatedByName = updatedByName; }
    }
    
    public static class BatchDeleteRequest {
        private List<String> ids;
        
        public List<String> getIds() { return ids; }
        public void setIds(List<String> ids) { this.ids = ids; }
    }
    
    public static class CopyFormRequest {
        private String name;
        private String title;
        private String copiedBy;
        private String copiedByName;
        
        public String getName() { return name; }
        public void setName(String name) { this.name = name; }
        public String getTitle() { return title; }
        public void setTitle(String title) { this.title = title; }
        public String getCopiedBy() { return copiedBy; }
        public void setCopiedBy(String copiedBy) { this.copiedBy = copiedBy; }
        public String getCopiedByName() { return copiedByName; }
        public void setCopiedByName(String copiedByName) { this.copiedByName = copiedByName; }
    }
    
    public static class BatchUpdateSortRequest {
        private List<FormSort> formSorts;
        
        public List<FormSort> getFormSorts() { return formSorts; }
        public void setFormSorts(List<FormSort> formSorts) { this.formSorts = formSorts; }
        
        public static class FormSort {
            private String id;
            private Integer sortOrder;
            
            public String getId() { return id; }
            public void setId(String id) { this.id = id; }
            public Integer getSortOrder() { return sortOrder; }
            public void setSortOrder(Integer sortOrder) { this.sortOrder = sortOrder; }
        }
    }
    
    public static class ValidateFieldsRequest {
        private List<Form.FormField> fields;
        
        public List<Form.FormField> getFields() { return fields; }
        public void setFields(List<Form.FormField> fields) { this.fields = fields; }
    }
}